'use strict'

let errors = require('../../config/errors');
let models = require('../models');
let lib = {
    util: require('../lib/util'),
    menus: require('../lib/menus')
};

let Attendance = models.Attendance;
let AttendanceStatus = models.AttendanceStatus;

let studentService = require('../services/student');
let absenceApplyService = require('../services/absenceapply');
let checkTimeSetService = require('../services/checktimeset');
let attendanceService = require('../services/attendance');
let trackService = require('../services/track');
let festivalService = require('../services/festival');

let viewCheckTimes = {
    login: true,
    privileges: [ 'student' ],
    handler(req, res) {
        let user = req.session.login.user;
        let student = studentService.getStudentByUserId(user.id);
        let checkTimeSet = checkTimeSetService.getCheckTimeSetOfStudent(student);
        let recentFestival = festivalService.getRecentFestivalOfStudent(student);

        res.render('public/main', {
            title: '测试页面',
            basePath: '',
            menus: lib.menus.generateMenus(user),
            role: 'student',
            selectedTab: 'index',
            selectedMenu: 'time',
            student: student,
            user: student,
            checkTimeSet: checkTimeSet,
            recentFestival: recentFestival,
            lib: lib
        });
    }
};

let viewTodayAttendance = {
    login: true,
    privileges: [ 'student' ],
    handler(req, res) {
        let user = req.session.login.user;
        let student = studentService.getStudentByUserId(user.id);

        let school = studentService.getSchoolOfStudent(student);
        console.log(school.terms);

        let term = null;
        if ( school.terms.length > 0 ) {
            let termId = req.query.term;
            if ( termId ) {
                term = school.terms.find(term => term.id == termId);
            }
            else {
                let today = new Date();
                term = school.terms.find(term => {
                    return term.startTime <= today && term.endTime >= today;
                });
            }
        }

        let attendances = [];
        if ( term ) {
            attendances = attendanceService.getAttendancesOfStudent(student, term.startTime, term.endTime);
        }

        let attendanceObjects = Attendance.toObjectArray(attendances, {
            includes: [ 
                { 'student': [ 'name', 'sid' ] },
                'date', 
                { 'values': ['enterStatus', 'exitStatus'] }
            ]
        });

        res.render('public/main', {
            basePath: '',
            title: '考勤概况',
            menus: lib.menus.generateMenus(user),
            role: 'student',
            selectedTab: 'index',
            selectedMenu: 'today',
            student: student,
            user: student,
            attendanceObjects: attendanceObjects,
            terms: school.terms
        });
    }
};

let viewQueryAttendance = {
    login: true,
    privileges: [ 'student' ],
    handler(req, res) {
        let user = req.session.login.user;
        let student = studentService.getStudentByUserId(user.id);
        let checkTimeSet = checkTimeSetService.getCheckTimeSetOfStudent(student);

        let startTime = new Date(Number(req.query.start));
        let endTime = new Date(Number(req.query.end));
        let queryStatus = req.query.status;

        let now = new Date();
        if ( !req.query.start ) {
            startTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, -1);
        }
        if ( !req.query.end ) {
            endTime = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59);
        }
        if ( !queryStatus ) {
            queryStatus = 0;
        }

        let attendances = attendanceService.queryAttendancesOfStudent(student, startTime, endTime, queryStatus);
        let tracksList = trackService.getTracksByAttendances(attendances);
        let absenceApplies = absenceApplyService.getAppliesOfStudent(student);
        let recentFestival = festivalService.getRecentFestivalOfStudent(student);

        console.log(attendances.length);

        // 格式化部分信息
        tracksList.forEach(tracks => {
            tracks.forEach(track => {
                track.description = trackService.formatTrack(track);
            });
        });

        res.render('public/main', {
            basePath: '',
            title: '考勤查询',
            menus: lib.menus.generateMenus(user),
            role: 'student',
            selectedTab: 'attendance',
            selectedMenu: 'search',
            student: student,
            user: student,
            checkTimeSet: checkTimeSet,
            attendances: attendances,
            tracksList: tracksList,
            absenceApplies: absenceApplies,
            AbsenceApplyStatus: models.AbsenceApplyStatus,
            AttendanceDescriptions: models.AttendanceDescriptions,
            recentFestival: recentFestival,
            lib: lib
        });
    }
};

let viewAddAbsenceApply = {
    login: true,
    privileges: [ 'student' ],
    handler(req, res) {
        let user = req.session.login.user;
        let student = studentService.getStudentByUserId(user.id);

        res.render('public/main', {
            basePath: '',
            title: '新建假条',
            menus: lib.menus.generateMenus(user),
            role: 'student',
            selectedTab: 'absence_apply',
            selectedMenu: 'add',
            student: student,
            user: student
        });
    }
};

let viewHistoryAbsenceApply = {
    login: true,
    privileges: [ 'student' ],
    handler(req, res) {
        let user = req.session.login.user;
        let student = studentService.getStudentByUserId(user.id);
        let absenceApplies = absenceApplyService.getAppliesOfStudent(student);

        res.render('public/main', {
            basePath: '',
            title: '历史假条',
            menus: lib.menus.generateMenus(user),
            role: 'student',
            selectedTab: 'absence_apply',
            selectedMenu: 'history',
            student: student,
            user: student,
            absenceApplies: absenceApplies,
            AbsenceApplyStatus: models.AbsenceApplyStatus,
            AttendanceDescriptions: models.AttendanceDescriptions,
            lib: lib
        });
    }
};

let viewTest = {
    login: true,
    privileges: [ 'student' ],
    handler(req, res) {
        let user = req.session.login.user;
        let student = studentService.getStudentByUserId(user.id);

        res.render('public/main', {
            basePath: '',
            menus: menus,
            role: 'student',
            selectedTab: 'test',
            selectedMenu: 'test',
            title: '测试页面',
            user: student,
            message: 'hello, world'
        });
    }
};

let actionSubmitAbsenceApply = {
    login: true,
    privileges: [ 'student' ],
    handler(req, res) {
        let user = req.session.login.user;
        let student = studentService.getStudentByUserId(user.id);
        let applyData = req.body.apply;

        let absenceApply = absenceApplyService.submitAbsenceApply(student, applyData);

        res.json({
            successful: true,
            data: {
                absenceApply: absenceApply.toObject()
            }
        });
    }
};

let actionUpdateAbsenceApply = {
    login: true,
    privileges: [ 'student' ],
    handler(req, res) {
        let user = req.session.login.user;
        let student = studentService.getStudentByUserId(user.id);
        let applyData = req.body.apply;

        let absenceApply = absenceApplyService.updateAbsenceApply(student, applyData);

        res.json({
            successful: true,
            data: {
                absenceApply: absenceApply.toObject()
            }
        });
    }
};

let actionQueryAttendanceDetails = {
    handler(req, res) {
        let studentIFlyId = req.params.studentId;
        
        let student = studentService.getStudentByIFlyId(studentIFlyId);
        if ( !student ) {
            throw errors.StudentNotFound;
        }

        let attendances = [];

        // 根据时间筛选
        if ( req.query.start && req.query.end ) {
            let startTime = new Date(Number(req.query.start));
            let endTime = new Date(Number(req.query.end));

            attendances = attendanceService.queryAttendancesOfStudent(student, startTime, endTime, 0);
        }
        else {
            attendances = attendanceService.getAttendancesOfStudentThisWeek(student);
        }

        // 分页（尚未集成查询分页）
        if ( 'page' in req.query ) {
            let page = req.query.page;
            let pageSize = 20;
            if ( 'page_size' in req.query ) {
                pageSize = req.query.page_size;
            }

            attendances = attendances.slice(page * pageSize, (page + 1) * pageSize);
        }

        let attendanceObjects = Attendance.toObjectArray(
                attendances, {
                includes: [ 
                    { 'student': [ 'name', 'sid' ] },
                    'date', 
                    { 'values': ['enterStatus', 'exitStatus'] }
                ]
            }
        );

        attendanceObjects.forEach(attendanceObject => {
            attendanceObject.values.forEach((value, index) => {
                value.enterTime = attendanceObject.date.getTime() + 7 * index * 60 * 1000;
                value.exitTime = attendanceObject.date.getTime() + (7 * index + 2) * 60 * 1000;
            });
            attendanceObject.date = attendanceObject.date.getTime();
        });

        res.json({
            successful: true,
            data: {
                attendances: attendanceObjects
            }
        });
    }
};

function isErrorStatus(status) {
    return status == AttendanceStatus.Absent ||
        status == AttendanceStatus.Late ||
        status == AttendanceStatus.Early;
}

let actionQueryAttendanceErrors = {
    handler(req, res) {
        let studentIFlyId = req.params.studentId;
        
        let student = studentService.getStudentByIFlyId(studentIFlyId);
        if ( !student ) {
            throw errors.StudentNotFound;
        }

        let attendances = [];

        if ( req.query.start && req.query.end ) {
            let startTime = new Date(Number(req.query.start));
            let endTime = new Date(Number(req.query.end));

            attendances = attendanceService.queryAttendancesOfStudent(student, startTime, endTime, 0);
        }
        else {
            attendances = attendanceService.getAttendancesOfStudentThisWeek(student);
        }

        let attendanceObjects = Attendance.toObjectArray(
                attendances, {
                includes: [ 
                    { 'student': [ 'name', 'sid' ] },
                    'date', 
                    { 'values': ['enterStatus', 'exitStatus'] }
                ]
            }
        );

        // 删除正常出勤
        attendanceObjects = attendanceObjects.filter(attendanceObject => {
            let index = 0;
            attendanceObject.values = attendanceObject.values.filter(value => {
                let isError = false;
                if ( !isErrorStatus(value.enterStatus) ) {
                    delete value.enterStatus;
                }
                else {
                    value.enterTime = attendanceObject.date.getTime() + 7 * index * 60 * 1000;
                    isError = true;
                }

                if ( !isErrorStatus(value.exitStatus) ) {
                    delete value.exitStatus;
                }
                else {
                    value.exitTime = attendanceObject.date.getTime() + (7 * index + 2) * 60 * 1000;
                    isError = true;
                }

                index += 1;
                return isError;
            });

            attendanceObject.date = attendanceObject.date.getTime();
            return attendanceObject.values.length > 0;
        });
        
        res.json({
            successful: true,
            data: {
                attendances: attendanceObjects
            }
        });
    }
};

module.exports = {
    viewCheckTimes,
    viewTodayAttendance,
    viewQueryAttendance,
    viewAddAbsenceApply,
    viewHistoryAbsenceApply,
    viewTest,
    actionSubmitAbsenceApply,
    actionUpdateAbsenceApply,
    actionQueryAttendanceDetails,
    actionQueryAttendanceErrors
};
